using System.Collections.Generic;
using UnityEngine;

public class GestureTracker
{
	public struct OrtogonalDistance
	{
		public FingerPos pos;

		public float distance;
	}

	public float minDistance = 0.05f;

	public float minDistanceScreen;

	protected LinkedList<FingerPos> fingerPosQueue = new LinkedList<FingerPos>();

	public int MaxQueueSize = 50;

	public Vector3 FirstPos()
	{
		if (fingerPosQueue.First == null)
		{
			return Input.mousePosition;
		}
		return fingerPosQueue.First.Value.screenPos;
	}

	public Vector3 LastPos()
	{
		if (fingerPosQueue.Last == null)
		{
			return Input.mousePosition;
		}
		return fingerPosQueue.Last.Value.screenPos;
	}

	public void AddScreenPos(Vector3 pos, Camera camera, Plane plane, float realTime)
	{
		Ray ray = camera.ScreenPointToRay(pos);
		float enter = 0f;
		if (plane.Raycast(ray, out enter))
		{
			Vector3 point = ray.GetPoint(enter);
			AddPos(new FingerPos
			{
				pos = point,
				screenPos = pos,
				realTime = realTime
			});
		}
	}

	public void AddPos(FingerPos pos)
	{
		LinkedListNode<FingerPos> last = fingerPosQueue.Last;
		if (last != null && (Vector3.Distance(last.Value.pos, pos.pos) <= minDistance || Vector3.Distance(last.Value.screenPos, pos.screenPos) <= minDistanceScreen))
		{
			FingerPos value = last.Value;
			value.deltaTime += pos.deltaTime;
			value.realTime = pos.realTime;
			last.Value = value;
			return;
		}
		fingerPosQueue.AddLast(pos);
		int num = Mathf.Max(0, fingerPosQueue.Count - MaxQueueSize);
		for (int i = 0; i < num; i++)
		{
			fingerPosQueue.RemoveFirst();
		}
	}

	public void Clear()
	{
		fingerPosQueue.Clear();
	}

	public int Count()
	{
		return fingerPosQueue.Count;
	}

	public LinkedList<FingerPos> GetQueue()
	{
		return fingerPosQueue;
	}

	public Vector3 CalculateAverageVelocity()
	{
		Vector3 zero = Vector3.zero;
		if (fingerPosQueue.Count < 2)
		{
			return zero;
		}
		LinkedList<FingerPos>.Enumerator enumerator = fingerPosQueue.GetEnumerator();
		enumerator.MoveNext();
		FingerPos fingerPos = enumerator.Current;
		do
		{
			FingerPos current = enumerator.Current;
			zero += (current.pos - fingerPos.pos) / current.deltaTime / (fingerPosQueue.Count - 1);
			fingerPos = current;
		}
		while (enumerator.MoveNext());
		return zero;
	}

	public Vector3 CalculateFirstToLastPoint()
	{
		if (fingerPosQueue.Count < 2)
		{
			return Vector3.zero;
		}
		return fingerPosQueue.Last.Value.pos - fingerPosQueue.First.Value.pos;
	}

	public OrtogonalDistance CalculateMaxOrtogonalDistance()
	{
		OrtogonalDistance result = default(OrtogonalDistance);
		if (fingerPosQueue.Count < 3)
		{
			return result;
		}
		Vector3 vector = CalculateFirstToLastPoint();
		Vector3 normalized = new Vector3(vector.y, 0f - vector.x, 0f).normalized;
		int num = 0;
		Debug.Log(string.Concat("Cue ORTO COUNT ", fingerPosQueue.Count, " orto Direction ", normalized, " direction ", vector));
		FingerPos value = fingerPosQueue.First.Value;
		foreach (FingerPos item in fingerPosQueue)
		{
			Vector3 rhs = item.pos - value.pos;
			rhs.z = 0f;
			float num2 = Vector3.Dot(normalized, rhs);
			if (Mathf.Abs(result.distance) < Mathf.Abs(num2))
			{
				result.pos = item;
				result.distance = num2;
			}
			num++;
		}
		return result;
	}

	public OrtogonalDistance CalculateMaxOrtogonalDistanceXZPlane()
	{
		OrtogonalDistance result = default(OrtogonalDistance);
		if (fingerPosQueue.Count < 3)
		{
			return result;
		}
		Vector3 lhs = CalculateFirstToLastPoint();
		Vector3 normalized = Vector3.Cross(lhs, Vector3.up).normalized;
		int num = 0;
		FingerPos value = fingerPosQueue.First.Value;
		foreach (FingerPos item in fingerPosQueue)
		{
			Vector3 normalized2 = (item.pos - value.pos).normalized;
			normalized2.y = 0f;
			float num2 = Vector3.Dot(normalized, normalized2);
			if (Mathf.Abs(result.distance) < Mathf.Abs(num2))
			{
				result.pos = item;
				result.distance = num2;
			}
			num++;
		}
		return result;
	}

	public float FirstToLastTime()
	{
		if (fingerPosQueue.Count < 2)
		{
			return 0f;
		}
		return fingerPosQueue.Last.Value.realTime - fingerPosQueue.First.Value.realTime;
	}

	public Vector3 FirstToLastScreen()
	{
		if (fingerPosQueue.Count < 2)
		{
			return Vector3.zero;
		}
		return fingerPosQueue.Last.Value.screenPos - fingerPosQueue.First.Value.screenPos;
	}

	public float FirstToLastSpeed()
	{
		if (fingerPosQueue.Count < 2)
		{
			return 0f;
		}
		return (fingerPosQueue.Last.Value.pos - fingerPosQueue.First.Value.pos).magnitude / Mathf.Max(0.001f, fingerPosQueue.Last.Value.realTime - fingerPosQueue.First.Value.realTime);
	}
}
